package com.emergency.embackend.service.impl;

import com.emergency.embackend.entity.HelpData;
import com.emergency.embackend.entity.Share;
import com.emergency.embackend.mapper.HelpDataMapper;
import com.emergency.embackend.mapper.ShareDataMapper;
import com.emergency.embackend.mapper.WikiArticleMapper;
import com.emergency.embackend.mapper.WikiVideoMapper;
import com.emergency.embackend.param.ArticleParam;
import com.emergency.embackend.param.VideoParam;
import com.emergency.embackend.service.DataViewService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author chddd
 * @description
 * @create 2024/3/27 22:44:23
 */
@Service
@Slf4j
public class DataViewServiceImpl implements DataViewService {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private WikiVideoMapper videoMapper;
    @Autowired
    private WikiArticleMapper articleMapper;
    @Autowired
    private ShareDataMapper shareDataMapper;
    @Autowired
    private HelpDataMapper helpDataMapper;

    @Override
    public void fillViews(String viewKey,char type){
        //获取对应类型的浏览量的key
        //Set<String> keys = stringRedisTemplate.keys(viewKey);

        ScanOptions scanOptions = ScanOptions.scanOptions().match(viewKey + "*").build();
        Set<String> keys = stringRedisTemplate.execute((connection) -> {
            Set<String> keysResult = new HashSet<>();
            try (Cursor<byte[]> cursor = connection.scan(scanOptions)) {
                while (cursor.hasNext()) {
                    byte[] next = cursor.next();
                    keysResult.add(new String(next));
                }
            }
            return keysResult;
        }, true);
        if(CollectionUtils.isEmpty(keys)){
            return ;
        }
        Map<Long,Long> map =new HashMap<>(keys.size()+1);
        //遍历key
        //需要根据对应的id值塞入数据
        keys.forEach(e->{
            String[] key = e.split(":");
            //以id为key,当前redis的浏览量为value
            if(stringRedisTemplate.opsForValue().get(e)!=null) {
                map.put(Long.valueOf(key[key.length - 1]), Long.valueOf(stringRedisTemplate.opsForValue().get(e)));
            }else{
                map.put(Long.valueOf(key[key.length - 1]),0L);
            }
        });
        //判断是哪个类型的数据
        switch (type){
            //视频
            case '0':
            //获取原视频的数据量,并且修改
             updateVideoView(map,keys);
                break;
            //文章
            case '1':
                updateArticleView(map,keys);
                break;
            //分享
            case '2':
               updateShareView(map,keys);
                break;
            //求助
            case '3':
             updateHelpView(map,keys);
                break;
            default:
                break;
        }
        stringRedisTemplate.delete(keys);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updateHelpView(Map<Long, Long> map, Set<String> keys) {
        map.entrySet().forEach(entry->{
            HelpData help = new HelpData();
            Long helpId = entry.getKey();
            Long redisViewCount = entry.getValue();
            Long viewCount = helpDataMapper.getViewCount(helpId);
            if(viewCount!=null) {
                help.setHelpId(helpId);
                help.setView(redisViewCount + viewCount);
                log.info("help数据:{}", help);
                helpDataMapper.update(help);
            }
        });
        keys.forEach(e->{
            log.info("key++++++++{}",e);
        });
        stringRedisTemplate.delete(keys);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updateVideoView(Map<Long,Long> map,Set<String> keys){
        map.entrySet().forEach(entry->{
            VideoParam videoParam = new VideoParam();
            Long videoId = entry.getKey();
            Long redisViewCount = entry.getValue();
            Long viewCount = videoMapper.getViewCount(videoId);
            if(viewCount!=null) {
                videoParam.setId(videoId);
                videoParam.setViewCount(redisViewCount + viewCount);
                log.info("video数据:{}", videoParam);
                videoMapper.update(videoParam);
            }
        });
        keys.forEach(e->{
            log.info("key++++++++{}",e);
        });
        stringRedisTemplate.delete(keys);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updateArticleView(Map<Long,Long> map,Set<String> keys){
        map.entrySet().forEach(entry->{
            ArticleParam articleParam = new ArticleParam();
            Long videoId = entry.getKey();
            Long redisViewCount = entry.getValue();
            Long viewCount = articleMapper.getViewCount(videoId);
            if(viewCount!=null) {
                articleParam.setId(videoId);
                articleParam.setViewCount(redisViewCount + viewCount);
                log.info("article数据:{}", articleParam);
                articleMapper.update(articleParam);
            }
        });
        keys.forEach(e->{
            log.info("key++++++++{}",e);
        });
        stringRedisTemplate.delete(keys);
    }
    @Transactional(rollbackFor = Exception.class)
    public void updateShareView(Map<Long,Long> map,Set<String> keys){
        map.entrySet().forEach(entry->{
            Share share = new Share();
            Long shareId = entry.getKey();
            Long redisViewCount = entry.getValue();
            Long viewCount = shareDataMapper.getViewCount(shareId);
            if(viewCount!=null) {
                share.setId(shareId);
                share.setViewCount(redisViewCount + viewCount);
                log.info("share数据:{}", share);
                shareDataMapper.update(share);
            }
        });
        keys.forEach(e->{
            log.info("key++++++++{}",e);
        });
        stringRedisTemplate.delete(keys);
    }
    @Override
    public Long getViewCount(String key) {
        Long view = 0L;
        if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(key))){
            String viewStr = stringRedisTemplate.opsForValue().get(key);
            if(viewStr!=null){
                view =  Long.valueOf(viewStr);
            }
        }
        return view;
    }
}
